﻿using Fiddler;
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;

namespace FxSuperCore.Utils
{
	public static class FiddlerUtils
	{
		/// <summary>
		/// 事件表
		/// </summary>
		private static ConcurrentDictionary<string, Action<Session>> eventDic = new ConcurrentDictionary<string, Action<Session>>();

		/// <summary>
		/// 是否开启了监听
		/// </summary>
		private static volatile bool isStart = false;

		/// <summary>
		/// 引用数量
		/// </summary>
		private static volatile int _refNum = 0;

		/// <summary>
		/// 设置代理选项
		/// </summary>
		/// <param name="hInternet"></param>
		/// <param name="dwOption"></param>
		/// <param name="lpBuffer"></param>
		/// <param name="lpdwBufferLength"></param>
		/// <returns></returns>
		[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
		private static extern bool InternetSetOption(
			int hInternet,
			int dwOption,
			IntPtr lpBuffer,
			int lpdwBufferLength);


		/// <summary>
		/// 安装证书
		/// </summary>
		/// <returns></returns>
		public static bool InstallCertificate()
		{
			var rootCert = CertMaker.GetRootCertificate();
			if (rootCert == null)
			{
				CertMaker.createRootCert();
				CertMaker.trustRootCert();
			}
			return true;
		}

		/// <summary>
		/// 信任证书
		/// </summary>
		public static void TrustCetification()
		{
			var rootCert = CertMaker.GetRootCertificate();
			CertMaker.trustRootCert();
			if (rootCert != null)
			{
				FiddlerApplication.oDefaultClientCertificate = rootCert;
				CONFIG.IgnoreServerCertErrors = true;
			}
		}


		/// <summary>
		/// 卸载证书,通常不用
		/// </summary>
		/// <returns></returns>
		public static bool UninstallCertificate()
		{
			if (CertMaker.GetRootCertificate() != null)
			{
				if (!CertMaker.removeFiddlerGeneratedCerts(true))
					return false;
			}
			return true;
		}

		/// <summary>
		/// 开启网络监听
		/// </summary>
		private static void StartListener()
		{
			if (!isStart)
			{
				lock (typeof(FiddlerUtils))
				{
					if (!isStart)
					{
						int port = CommonUtils.GetCanUsePort(8877);
						FiddlerApplication.Startup(port, true, true, true);
						isStart = true;
					}
				}
			}
		}


		/// <summary>
		/// 停止网络监听
		/// </summary>
		private static void StopNetListener()
		{
			lock (typeof(FiddlerUtils))
			{
				FiddlerApplication.Shutdown();
				SetCleanIEProxy();
				isStart = false;
			}
		}


		/// <summary>
		/// 清空IE代理设置
		/// </summary>
		/// <returns></returns>
		private static bool SetCleanIEProxy()
		{
			try
			{
				Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true);
				rk.SetValue("ProxyEnable", 0);
				rk.Flush();//刷新注册表
				rk.Close();
				ActivateIEProxy();
				return true;
			}
			catch { return false; }
		}


		/// <summary>
		/// 激活IE设置
		/// </summary>
		private static void ActivateIEProxy()
		{
			InternetSetOption(0, 39, IntPtr.Zero, 0);
			InternetSetOption(0, 37, IntPtr.Zero, 0);
		}

		public static void Start()
		{
			lock (typeof(FiddlerUtils))
			{
				StartListener();
				Interlocked.Increment(ref _refNum);
			}
		}

		public static void Stop()
		{
			lock (typeof(FiddlerUtils))
			{
				int newVol = Interlocked.Decrement(ref _refNum);
				if (newVol <= 0)
				{
					StopNetListener();
				}
			}
		}
	}
}
